package com.paad.todolist;

import java.util.ArrayList;
import java.util.Random;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

enum phase {
	select, move, attack
}

public class BattlegridActivity extends Activity {

	static final int rows = 11;
	static final int cols = 7; // remember to update battlegrid.xml if you
								// change this

	phase currentPhase = phase.select;
	Tile active_unit = null;
	Random r;

	GridView myGridView;
	TileBattlegridAdapter aa;
	ArrayList<Tile> grid;
	ArmyDBAdapter armyDBAdapter;

	/** Called when the activity is first created. */
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.battlegrid);

		myGridView = (GridView) findViewById(R.id.gridView1);

		grid = new ArrayList<Tile>();
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

		// temp test code:
		// grid.add(new Tile());
		// grid.add(new Tile( new Squad() ));
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < cols; j++) {
				grid.add(new Tile());
			}
		}

		armyDBAdapter = new ArmyDBAdapter(this);
		// Open or create the database
		armyDBAdapter.open();

		Intent activation_intent = getIntent();
		int army1Id = activation_intent.getExtras().getInt("army1");
		int army2Id = activation_intent.getExtras().getInt("army2");

		Army army1 = new Army();
		Army army2 = new Army();

		army1.setId(army1Id);
		army2.setId(army2Id);

		Cursor itemIdCursor = armyDBAdapter.getArmyCursor(army1.getId());
		startManagingCursor(itemIdCursor);
		itemIdCursor.requery();
		Cursor itemCursor;
		if (itemIdCursor.moveToFirst())
			do {
				int item_id = itemIdCursor.getInt(itemIdCursor
						.getColumnIndex(ArmyDBAdapter.KEY_LISTING_SQUAD_ID));
				itemCursor = armyDBAdapter.getSquadCursor(item_id);
				if (itemCursor.moveToFirst()) {
					String name = itemCursor.getString(itemCursor
							.getColumnIndex(ArmyDBAdapter.KEY_SQUAD_TYPE));
					// Boolean is_done =
					// itemsCursor.getInt(itemsCursor.getColumnIndex(ShoppinglistsDBAdapter.KEY_ITEM_DONE))
					// > 0;
					int id = itemCursor.getInt(itemCursor
							.getColumnIndex(ArmyDBAdapter.KEY_ID));
					Squad newItem = new Squad(name);
					newItem.setId(id);
					newItem.setName(name);
					newItem.setTeam(true);
					// if(army1.pointsUsed < army1.squadPoints &&
					// army1.pointsUsed + newItem.squadPoints <=
					// army1.squadPoints){
					army1.addSquad(newItem);
					// army1.pointsUsed += newItem.squadPoints;
					// }
					itemCursor.close();
				}
			} while (itemIdCursor.moveToNext());

		itemIdCursor = armyDBAdapter.getArmyCursor(army2.getId());
		startManagingCursor(itemIdCursor);
		itemIdCursor.requery();
		if (itemIdCursor.moveToFirst())
			do {
				int item_id = itemIdCursor.getInt(itemIdCursor
						.getColumnIndex(ArmyDBAdapter.KEY_LISTING_SQUAD_ID));
				itemCursor = armyDBAdapter.getSquadCursor(item_id);
				if (itemCursor.moveToFirst()) {
					String name = itemCursor.getString(itemCursor
							.getColumnIndex(ArmyDBAdapter.KEY_SQUAD_TYPE));
					// Boolean is_done =
					// itemsCursor.getInt(itemsCursor.getColumnIndex(ShoppinglistsDBAdapter.KEY_ITEM_DONE))
					// > 0;
					int id = itemCursor.getInt(itemCursor
							.getColumnIndex(ArmyDBAdapter.KEY_ID));
					Squad newItem = new Squad(name);
					newItem.setId(id);
					newItem.setName(name);
					newItem.setTeam(false);
					// if(army2.pointsUsed < army2.squadPoints &&
					// army2.pointsUsed + newItem.squadPoints <=
					// army2.squadPoints){
					army2.addSquad(newItem);
					// army2.pointsUsed += newItem.squadPoints;
					// }
					itemCursor.close();
				}
			} while (itemIdCursor.moveToNext());

		r = new Random();

		// army1 and army2 are the armies to be generated, hopefully they are
		// correctly instantiated. go. do.

		for (int i = 0; i < army1.squads.size(); i++) {
			gridTileAt(i, 9).sq = army1.squads.get(i);
		}

		for (int i = 0; i < army2.squads.size(); i++) {
			gridTileAt(i, 1).sq = army2.squads.get(i);
		}

		/*
		 * gridTileAt(1,2).sq = new Squad("archerA", false); gridTileAt(2,2).sq
		 * = new Squad("swordsmanB", false); gridTileAt(3,2).sq = new
		 * Squad("cavalry", false); gridTileAt(4,2).sq = new Squad("swordsmanB",
		 * false); gridTileAt(5,2).sq = new Squad("archerA", false);
		 * 
		 * gridTileAt(1,8).sq = new Squad("cavalry", true); gridTileAt(2,8).sq =
		 * new Squad("swordsmanA", true); gridTileAt(3,8).sq = new
		 * Squad("archerB", true); gridTileAt(4,8).sq = new Squad("swordsmanA",
		 * true); gridTileAt(5,8).sq = new Squad("cavalry", true);
		 */

		int resID = R.layout.squad_battlegrid;
		aa = new TileBattlegridAdapter(this, resID, grid);
		myGridView.setAdapter(aa);

		// on Tile clicked.
		myGridView.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> av, View v, int position,
					long id) {
				Tile t = grid.get(position);
				int x = indexToX(position);
				int y = indexToY(position);

				if (currentPhase == phase.select) {
					if (t.sq != null && !t.sq.hasActed) {
						active_unit = t;
						setMoveTargets(x, y, t.sq.lowSpeed);
						currentPhase = phase.move;
					}
				} else

				if (currentPhase == phase.move) {
					if (t.validMoveTarget) {
						resetTileStates();
						if (t != active_unit) {
							move(active_unit, t);
							active_unit = t;
						}
						if (setAttackTargets(x, y, active_unit.sq.range,
								active_unit.sq.team)) {
							currentPhase = phase.attack;
						} else {
							active_unit.sq.hasActed = true;
							currentPhase = phase.select;
						}
					}
				} else

				if (currentPhase == phase.attack) {
					if (t.validAttackTarget) {
						resetTileStates();
						attack(active_unit, t);
						active_unit.sq.hasActed = true;
						currentPhase = phase.select;
					}
				}

				aa.notifyDataSetChanged();
				boolean end_turn = true;
				int t1_units = 0;
				int t2_units = 0;
				for (Tile tl : grid) {
					if (tl.sq != null && !tl.sq.hasActed) {
						end_turn = false;
					}
					if (tl.sq != null && tl.sq.team)
						t1_units++;
					else
						t2_units++;
				}
				if (end_turn) {
					resetUnitStates();
				}

				if (t1_units == 0) {
					Toast toast = Toast.makeText(getBaseContext(), "Red wins!",
							Toast.LENGTH_LONG);
					toast.show();
					finish();
				}
				if (t2_units == 0) {
					Toast toast = Toast.makeText(getBaseContext(),
							"Blue wins!", Toast.LENGTH_LONG);
					toast.show();
					finish();
				}
			}
		});

	}

	/** treats the list of tiles like a 2d array */
	Tile gridTileAt(int x, int y) {
		return grid.get(x + cols * y);
	}

	int indexToX(int index) {
		return index % cols;
	}

	int indexToY(int index) {
		return index / cols;
	}

	double distance(int x1, int y1, int x2, int y2) {
		return Math.sqrt(Math.pow(x1 - x2, 2.0) + Math.pow(y1 - y2, 2.0));
	}

	void resetTileStates() {
		for (Tile t : grid) {
			t.validAttackTarget = false;
			t.validMoveTarget = false;
		}
	}

	void resetUnitStates() {
		for (Tile t : grid) {
			if (t.sq != null) {
				t.sq.hasActed = false;
				t.sq.hasMoved = false;
			}
		}
	}

	void setMoveTargets(int x, int y, double radius) {
		for (int i = 0; i < grid.size(); i++) {
			if (distance(x, y, indexToX(i), indexToY(i)) <= radius) {
				Tile t = grid.get(i);
				if (t.sq == null || t == gridTileAt(x, y)) {
					t.validMoveTarget = true;
				}
			}
		}
	}

	boolean setAttackTargets(int x, int y, double radius, boolean team) {
		int valid_targets = 0;
		for (int i = 0; i < grid.size(); i++) {
			if (distance(x, y, indexToX(i), indexToY(i)) <= radius) {
				Tile t = grid.get(i);
				if (t.sq != null && t.sq.team != team) {
					valid_targets++;
					t.validAttackTarget = true;
				}
			}
		}
		return (valid_targets >= 1);
	}

	void move(Tile from, Tile to) {
		to.sq = from.sq;
		from.sq.hasMoved = true;
		from.sq = null;
	}

	void attack(Tile from, Tile to) {
		int kills = 0;
		for (Unit u : from.sq.units) {
			if (!to.sq.annihilated()
					&& to.sq.lowDef <= r.nextInt(u.dmgDie) + 1 + u.dmgMod) {
				to.sq.kill();
				kills++;

			}
		}
		String text = from.sq.name + " attack the " + to.sq.name
				+ " inflicting " + kills + " casualties!";
		Toast toast = Toast
				.makeText(getBaseContext(), text, Toast.LENGTH_SHORT);
		toast.show();

		if (to.sq.annihilated()) {
			to.sq = null;
		}
	}

}
